import { fixedNumber } from "./number";

/** mock分页列表
 * @param pageNum 页码
 * @param pageSize 每页数量
 * @param createItem 创建元素方法
 * @param total 总数量 默认66
 * @example const res = await MockList(1, 2, id => {id, name: `name_${idx}`}) // {total: 66, list: [{id: 1, name: 'name_1'}, {id: 2, name: 'name_2'}]}
 */
export function mockPageList<T>(pageNum: number, pageSize: number, createItem?: (idx: number) => T, total = 66): Promise<{total: number, list: T[]}> {
  const pageStart = (pageNum - 1) * pageSize
  const pageEnd   = pageNum * pageSize
  const currentSize = total < pageEnd ? total - pageStart : pageSize

  return new Promise(resolve => {
    setTimeout(() => {
      resolve({
        total,
        list: Array.from({length: currentSize}).map((_, idx) => createItem ? createItem(idx) : `#${pageNum}/${pageStart + idx + 1}_${Math.random().toString().slice(3,12)}`) as T[],
      })
    }, 1000);
  });
}

/** Returns a random number between min and max
 * @param max The maximum number
 * @param min The minimum number
 * @param len The number of decimal places to return
 * @example
 * mockNumber(100, 1, 2) // 80.99
 * mockNumber(100, 1, 3) // 12.123
 */
export const getNumber = (max: number, min = 99, len = 0) => fixedNumber(Math.random() * (max - min + 1) + min, len);


/** 从集合中任取一子元素
 * @param lib 集合
 * @returns 集合中任一子元素
 */
export const getItem = <T extends any>(lib: T[]): T => lib[Math.floor(getNumber(lib.length))];


export const LibByNumber = '0123456789'
export const LibByLowerCase = 'abcdefghijklmnopqrstuvwxyz'
export const LibByUpperCase = 'abcdefghijklmnopqrstuvwxyz'.toUpperCase()
export const LibBySpecialChar = '!@#$%^&,.'

export type RandomLibType = 'number' | 'lower-case' | 'upper-case' | 'special-char'
export interface RandomStringOptions {
  /** hash包含内容：number：数字，lower-case：小写字母，upper-case：大写字母，special-char：特殊字符 */
  includes?: RandomLibType[];
  /** 模板中的随机字符串 */
  randomKeyword?: string;
}

/** 创建hash
 * @param {string} template hash模板
 * @example getHash('****-****-admin-***') // 8f0c-c0a0-admin-01a
 */
export const getHash = (template: string = '****-*****-***********-******-**', options: RandomStringOptions = {}) => {
  const {
    includes = ['number', 'lower-case'],
    randomKeyword = '*'
  } = options

  let __: any = ''

  includes.includes('number') && (__ += LibByNumber);
  includes.includes('lower-case') && (__ += LibByLowerCase);
  includes.includes('upper-case') && (__ += LibByUpperCase);
  includes.includes('special-char') && (__ += LibBySpecialChar);

  const libs = __.split('')

  return template.split('').map(word => {
    if (word !== randomKeyword) return word
    else return getItem<string>(libs)
  }).join('')
}
